"""
Unified Monitoring Service
==========================

Provides a consolidated, stateless service for all monitoring operations, including
system metrics, service health checks, and alert management.
"""
import logging
import psutil
from typing import Dict, Any, List
from sqlalchemy.ext.asyncio import AsyncSession

from backend.shared import DatabaseFactory as UnifiedDatabaseManager
from backend.shared import RedisCache as RedisManager
from ..core.exceptions import MonitoringError # Assuming a custom exception class

logger = logging.getLogger(__name__)

# --- Prometheus Metrics Formatting ---
# In a real-world scenario, you would use the official prometheus_client library.
# This is a simplified representation for demonstration.

def _format_prometheus_metric(name: str, value: float, help_text: str, type: str = "gauge", labels: Dict[str, str] = None) -> str:
    """Helper to format a single metric in Prometheus text format."""
    label_str = ""
    if labels:
        label_str = "{" + ",".join([f'{k}="{v}"' for k, v in labels.items()]) + "}"
    
    lines = [
        f"# HELP {name} {help_text}",
        f"# TYPE {name} {type}",
        f"{name}{label_str} {value}"
    ]
    return "\n".join(lines)

# ------------------------------------

class MonitoringService:
    """The unified, stateless monitoring service."""

    def __init__(self, db_manager: UnifiedDatabaseManager, redis_manager: RedisManager, config: dict):
        self.db_manager = db_manager
        self.redis_manager = redis_manager
        self.config = config
        logger.info("Unified MonitoringService initialized.")

    async def get_system_metrics(self) -> Dict[str, Any]:
        """
        Collects and returns basic system metrics (CPU, Memory, Disk).
        
        Uses psutil to gather real system data.
        """
        try:
            cpu_usage = psutil.cpu_percent(interval=0.1)
            memory_info = psutil.virtual_memory()
            disk_info = psutil.disk_usage('/')

            return {
                "cpu": {
                    "usage_percent": cpu_usage,
                    "core_count": psutil.cpu_count(logical=True),
                },
                "memory": {
                    "total_gb": round(memory_info.total / (1024**3), 2),
                    "available_gb": round(memory_info.available / (1024**3), 2),
                    "used_percent": memory_info.percent,
                },
                "disk": {
                    "total_gb": round(disk_info.total / (1024**3), 2),
                    "used_gb": round(disk_info.used / (1024**3), 2),
                    "free_gb": round(disk_info.free / (1024**3), 2),
                    "used_percent": disk_info.percent,
                }
            }
        except Exception as e:
            logger.error(f"Failed to collect system metrics: {e}", exc_info=True)
            raise MonitoringError(f"Could not retrieve system metrics: {e}")

    async def get_prometheus_formatted_metrics(self) -> str:
        """
        Returns key system metrics in the Prometheus text-based format.
        """
        system_metrics = await self.get_system_metrics()
        
        metrics_parts = [
            _format_prometheus_metric(
                "redfire_system_cpu_usage_percent",
                system_metrics["cpu"]["usage_percent"],
                "Current system-wide CPU utilization as a percentage."
            ),
            _format_prometheus_metric(
                "redfire_system_memory_usage_percent",
                system_metrics["memory"]["used_percent"],
                "Current system-wide virtual memory utilization as a percentage."
            ),
            _format_prometheus_metric(
                "redfire_system_disk_usage_percent",
                system_metrics["disk"]["used_percent"],
                "Current disk utilization of the root partition as a percentage.",
                labels={"partition": "/"}
            )
        ]
        
        return "\n\n".join(metrics_parts) + "\n"

    async def list_alert_rules(self, db_session: AsyncSession) -> List[Dict[str, Any]]:
        """
        Lists alert rules from the database. (Conceptual)
        
        This method assumes an `alert_rules` table exists.
        """
        # In a real implementation:
        # result = await db_session.execute(text("SELECT * FROM alert_rules;"))
        # return [dict(row) for row in result.mappings()]
        logger.warning("Alert rule listing is not fully implemented; returning mock data.")
        return [
            {"id": 1, "name": "High CPU Usage", "metric": "cpu_usage", "threshold": 90, "status": "active"},
            {"id": 2, "name": "Low Disk Space", "metric": "disk_free", "threshold": 10, "status": "active"}
        ]

    # ... Other methods for creating/updating alerts, checking service health, etc. ...
